import { InventoryStatus, Product, ProductService, ProductStatus, ProductType } from "@mallfoundry/catalog"
import {
  Button,
  Card,
  Col,
  Divider,
  Form,
  Input,
  InputNumber,
  message as antMessage,
  PageHeader,
  Popconfirm,
  Radio,
  Row,
  Select,
  Space,
  Table,
  Tag,
} from "antd"
import { ColumnProps } from "antd/lib/table"
import * as _ from "lodash"
import * as React from "react"
import { useState } from "react"
import { Link, useHistory, useLocation, useParams } from "react-router-dom"
import { useSearchParams } from "../../hooks/location"
import { useProducts } from "../../hooks/product"
import { messageError } from "../../utils/reason"
import { useCollections } from "../collection"

import classes from "./product-list.module.scss"
import { useProductTypes } from "./product-type"

function renderProductStatus(product: Product) {
  if (product.status === ProductStatus.Active) {
    return <Tag color="success" style={{ margin: "0" }}>销售中</Tag>
  } else if (product.status === ProductStatus.Pending) {
    return <Tag color="processing" style={{ margin: "0" }}>审核中</Tag>
  } else if (product.status === ProductStatus.Archived) {
    return <Tag color="warning" style={{ margin: "0" }}>仓库中</Tag>
  } else if (product.status === ProductStatus.Disapproved) {
    return <Tag color="error" style={{ margin: "0" }}>已下架</Tag>
  } else if (product.inventoryStatus === InventoryStatus.OutOfStock) {
    return <Tag color="error" style={{ margin: "0" }}>已售罄</Tag>
  }
}

class ProductQueryParams {
  public name?: string
  public collections?: string[]
  public types?: ProductType[]
  public minPrice?: number
  public maxPrice?: number
  public statuses ?: ProductStatus | string
  public inventoryStatuses ?: InventoryStatus | string
}

function useProductQueryParams(searchParams: URLSearchParams) {
  const queryParams = new ProductQueryParams()
  const name = searchParams.get("name")
  if (name) {
    queryParams.name = name
  }

  const collections = searchParams.get("collections")
  if (collections) {
    queryParams.collections = _.split(collections, ",")
  }

  const types = searchParams.get("types")
  if (types) {
    queryParams.types = _.split(types, ",") as ProductType[]
  }

  const statuses = searchParams.get("statuses")
  if (statuses) {
    queryParams.statuses = statuses
  }

  const inventoryStatuses = searchParams.get("inventory_statuses")
  if (inventoryStatuses) {
    queryParams.inventoryStatuses = inventoryStatuses
  }

  const minPrice = searchParams.get("min_price")
  if (minPrice) {
    queryParams.minPrice = _.toNumber(minPrice)
  }

  const maxPrice = searchParams.get("max_price")
  if (maxPrice) {
    queryParams.maxPrice = _.toNumber(maxPrice)
  }

  return queryParams
}

export default function ProductList() {
  const history = useHistory()
  const location = useLocation()
  const searchParams = useSearchParams()
  const queryParams = useProductQueryParams(searchParams)
  const { storeId = "" } = useParams<{ storeId: string }>()
  const [collections] = useCollections(storeId)
  const [productTypes] = useProductTypes(storeId)
  const [form] = Form.useForm()
  const [loading, setLoading] = useState(false)

  const {
    loading: productsLoading,
    elements: products,
  } = useProducts({
    storeId, name: queryParams.name,
    minPrice: queryParams.minPrice,
    maxPrice: queryParams.maxPrice,
    collections: queryParams.collections,
    types: queryParams.types,
    statuses: queryParams.statuses,
    inventoryStatuses: queryParams.inventoryStatuses,
  })

  function deleteProduct(id: any) {
    ProductService.deleteProduct(id)
      .then(() => {
        antMessage.success("删除成功")
      })
      .catch(messageError)
      .finally(() => setLoading(false))
  }

  function publishProduct(id: any) {
    setLoading(true)
    ProductService.publishProduct(id)
      .then(() => {
        antMessage.success("上架成功")
      })
      .catch(messageError)
      .finally(() => setLoading(false))
  }

  function unpublishProduct(id: any) {
    setLoading(true)
    ProductService.unpublishProduct(id)
      .then(() => {
        antMessage.success("下架成功")
      })
      .catch(messageError)
      .finally(() => setLoading(false))
  }

  const columns: ColumnProps<Product>[] = [
    {
      title: "商品名称",
      dataIndex: "name",
      key: "name",
    },
    {
      title: "价格",
      dataIndex: "price",
      key: "price",
    },
    {
      title: "库存",
      dataIndex: "inventoryQuantity",
      key: "inventoryQuantity",
    },
    {
      title: "创建时间",
      dataIndex: "createdTime",
      key: "createdTime",
      width: "160px",
    },
    {
      title: "商品状态",
      dataIndex: "status",
      key: "status",
      align: "center",
      width: "88px",
      render: (status: ProductStatus, record: Product) => renderProductStatus(record),
    },
    {
      title: "操作",
      key: "actions",
      align: "right",
      width: "200px",
      render: (text: string, product: Product) => (
        <div className={classes.productListTableActions}>
          {
            product.status === ProductStatus.Active &&
            <>
              <Button type="link" size="small" style={{ margin: 0 }} onClick={() => unpublishProduct(product.id)}>下架</Button>
              <Divider type="vertical"/>
            </>
          }
          {
            product.status === ProductStatus.Archived &&
            <>
              <Button type="link" size="small" style={{ margin: 0 }} onClick={() => publishProduct(product.id)}>上架</Button>
              <Divider type="vertical"/>
            </>
          }
          <Link to={`/stores/${storeId}/products/${product.id}`}>修改</Link>
          <Divider type="vertical"/>
          <Popconfirm
            placement="bottomRight"
            onConfirm={() => deleteProduct(product.id)}
            title="确定删除这个商品集合?">
            <Button type="link" size="small" style={{ margin: 0 }}>删除</Button>
          </Popconfirm>
        </div>
      ),
    },
  ]

  const layout = {
    labelCol: { span: 6 },
    wrapperCol: { span: 18 },
  }

  function handleSearch() {
    form.validateFields()
      .then((values: ProductQueryParams) => {
        if (values.name) {
          searchParams.set("name", values.name)
        } else {
          searchParams.delete("name")
        }

        if (_.isEmpty(values.collections)) {
          searchParams.delete("collections")
        } else {
          searchParams.set("collections", _.join(values.collections))
        }

        if (_.isEmpty(values.types)) {
          searchParams.delete("types")
        } else {
          searchParams.set("types", _.join(values.types))
        }

        if (values.minPrice) {
          searchParams.set("min_price", _.toString(values.minPrice))
        } else {
          searchParams.delete("min_price")
        }

        if (values.maxPrice) {
          searchParams.set("max_price", _.toString(values.maxPrice))
        } else {
          searchParams.delete("max_price")
        }

        history.push(_.assign(location, {
          search: `?${searchParams.toString()}`,
        }))
      })
  }

  return (
    <div className={classes.productList}>
      <PageHeader title="商品管理" ghost={false}/>
      <Card className={classes.productListContent}>
        <Row gutter={[16, 16]}>
          <Col span={24}>
            <Card className={classes.filterBar} bordered={false}>
              <Form {...layout} form={form} initialValues={queryParams}
                    name="queryProductForm">
                <Row>
                  <Col span={6}>
                    <Form.Item name="name" label="商品名称">
                      <Input placeholder="请输入商品名称"/>
                    </Form.Item>
                  </Col>
                  <Col span={6}>
                    <Form.Item name="collections" label="商品分组">
                      <Select placeholder="请选择分组" mode="multiple">
                        {
                          _.map(collections, collection =>
                            <Select.Option key={collection.id}
                                           value={collection.id as string}
                                           children={collection.name}/>)
                        }
                      </Select>
                    </Form.Item>
                  </Col>
                  <Col span={6}>
                    <Form.Item name="types" label="商品类型">
                      <Select placeholder="请选择类型" mode="multiple">
                        {
                          _.map(productTypes, type =>
                            <Select.Option key={type.value} value={type.value} children={type.text}/>)
                        }
                      </Select>
                    </Form.Item>
                  </Col>
                </Row>
                <Row>
                  <Col span={6}>
                    <Form.Item label="价格" style={{ marginBottom: 0 }}>
                      <Form.Item name="minPrice" style={{ display: "inline-block", width: "calc(50% - 12px)" }}>
                        <InputNumber
                          style={{ width: "100%" }}
                          precision={2}
                          min={0}
                          formatter={value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
                          parser={(value ?: string) => _.isUndefined(value) ? 0 : value.replace(/¥\s?|(,*)/g, "")}/>
                      </Form.Item>
                      <span style={{
                        display: "inline-block",
                        width: "24px",
                        lineHeight: "32px",
                        textAlign: "center",
                      }}>-</span>
                      <Form.Item name="maxPrice" style={{ display: "inline-block", width: "calc(50% - 12px)" }}>
                        <InputNumber
                          style={{ width: "100%" }}
                          precision={2}
                          min={0}
                          formatter={value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
                          parser={(value ?: string) => _.isUndefined(value) ? 0 : value.replace(/¥\s?|(,*)/g, "")}/>
                      </Form.Item>
                    </Form.Item>
                  </Col>
                </Row>
                <Row>
                  <Col span={6}>
                    <Row>
                      <Col offset={6}>
                        <Space>
                          <Button type="primary" onClick={handleSearch} loading={loading || productsLoading}>筛选</Button>
                          <Button onClick={() => form.resetFields()}>重置</Button>
                        </Space>
                      </Col>
                    </Row>
                  </Col>
                </Row>
              </Form>
            </Card>
          </Col>
        </Row>
        <Row gutter={[16, 16]}>
          <Col>
            <Space>
              <Radio.Group value={queryParams.statuses || queryParams.inventoryStatuses} onChange={e => {
                const status = e.target.value
                if (status === InventoryStatus.OutOfStock) {
                  searchParams.delete("statuses")
                  searchParams.set("inventory_statuses", status)
                } else if (_.isEmpty(status)) {
                  searchParams.delete("inventory_statuses")
                  searchParams.delete("statuses")
                } else {
                  searchParams.delete("inventory_statuses")
                  searchParams.set("statuses", status)
                }
                history.push(_.assign(location, {
                  search: `?${searchParams.toString()}`,
                }))
              }}>
                <Radio.Button
                  checked={_.isEmpty(queryParams.statuses) && _.isEmpty(queryParams.inventoryStatuses)}>全部</Radio.Button>
                <Radio.Button value={ProductStatus.Active}>销售中</Radio.Button>
                <Radio.Button value={InventoryStatus.OutOfStock}>已售罄</Radio.Button>
                <Radio.Button
                  value={_.join([ProductStatus.Archived, ProductStatus.Disapproved, ProductStatus.Pending])}
                >仓库中</Radio.Button>
              </Radio.Group>
              <Button type="primary">
                <Link to={`/stores/${storeId}/products/new`}>创建新商品</Link>
              </Button>
            </Space>
          </Col>
        </Row>
        {/*<Row gutter={[16, 16]} align="middle">
          <Col>
            <Space>
              <Button>下架</Button>
              <Button>删除</Button>
              <Button>改分组</Button>
              <Button>批量设置</Button>
            </Space>
          </Col>
        </Row>*/}
        <Row>
          <Col span={24}>
            <Table rowKey="id" columns={columns} loading={loading || productsLoading}
                   dataSource={products}/>
          </Col>
        </Row>
      </Card>
    </div>
  )
}
